/*
 * 版权所有 (c) 2022-2099 TBIT。保留所有权利。
 */

package com.tbit.main.remote.rpc;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.tbit.Version;
import com.tbit.common.constant.SystemConstant;
import com.tbit.common.utils.TraceUtil;
import com.tbit.main.util.OrderSourceUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.NameValuePair;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.*;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import java.io.IOException;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author <a href="mailto:li.yao@tbit.com.cn">yao</a>
 * @since 2024/7/9 14:43
 */
@Slf4j
public class UQHttpUtil {

    @SneakyThrows
    public static String sendGet(final String url, final Map<String, Object> params) {
        if (CollUtil.isEmpty(params)) {
            return doSendRequest(new HttpGet(url));
        }

        List<NameValuePair> nvps = params.entrySet().stream()
                .filter(entry -> Objects.nonNull(entry.getValue()))
                .map(entry -> new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue())))
                .collect(Collectors.toList());
        URI uri = new URIBuilder(url, StandardCharsets.UTF_8).addParameters(nvps).build();
        HttpGet httpGet = new HttpGet(uri);
        return doSendRequest(httpGet);
    }

    public static String sendPut(final String url, final Map<String, Object> params) {
        return sendRequest(new HttpPut(url), params);
    }

    public static String sendJsonPut(final String url, final Map<String, Object> params) {
        return sendJsonRequest(new HttpPut(url), JSONUtil.toJsonStr(params));
    }

    private static String sendJsonRequest(HttpEntityEnclosingRequestBase httpEntityEnclosingRequestBase, final String params) {
        httpEntityEnclosingRequestBase.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType());
        if (StrUtil.isBlank(params)) {
            return doSendRequest(httpEntityEnclosingRequestBase);
        }

        httpEntityEnclosingRequestBase.setEntity(new StringEntity(params, StandardCharsets.UTF_8));

        return doSendRequest(httpEntityEnclosingRequestBase);
    }

    private static String sendRequest(HttpEntityEnclosingRequestBase httpEntityEnclosingRequestBase, final Map<String, Object> params) {
        httpEntityEnclosingRequestBase.setHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_FORM_URLENCODED.getMimeType());
        if (CollUtil.isEmpty(params)) {
            return doSendRequest(httpEntityEnclosingRequestBase);
        }

        List<org.apache.http.NameValuePair> nvps = params.entrySet().stream()
                .filter(entry -> Objects.nonNull(entry.getValue()))
                .map(entry -> new BasicNameValuePair(entry.getKey(), String.valueOf(entry.getValue())))
                .collect(Collectors.toList());
        httpEntityEnclosingRequestBase.setEntity(new UrlEncodedFormEntity(nvps, StandardCharsets.UTF_8));

        return doSendRequest(httpEntityEnclosingRequestBase);
    }

    private static String doSendRequest(HttpRequestBase httpRequest) {
        String result = null;
        httpRequest.setHeader(SystemConstant.U_APP_VERSION, Version.VERSION);
        httpRequest.setHeader(SystemConstant.TRACE_ID, TraceUtil.getTraceIdByLocal());
        httpRequest.setHeader(SystemConstant.ORDER_SOURCE, String.valueOf(OrderSourceUtils.getOrderSource()));

        // 设置超时时间
        httpRequest.setConfig(RequestConfig.custom()
                .setConnectTimeout(10000)
                .setConnectionRequestTimeout(10000)
                .setSocketTimeout(10000)
                .build());

        try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
            try (CloseableHttpResponse response = httpClient.execute(httpRequest)) {
                // 获取状态码
                HttpEntity entity = response.getEntity();
                // 获取响应信息
                result = EntityUtils.toString(entity);
                // 确保流被完全消费
                EntityUtils.consume(entity);
            }
        } catch (IOException e) {
            log.error("[UQHttpClient][doGet][error: {}]", e.getMessage(), e);
        }

        return result;
    }

}
